/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "Vk图像.h"

#include "纹理/纹理.h"


static S_键值序列容器<uint32, S_VkImage*> g_纹理容器;



void f_vkImage_setLayout(VkCommandBuffer cmd, VkImage image,
						VkImageAspectFlags aspectMask,
						VkImageLayout old_image_layout,
						VkImageLayout new_image_layout,
						int32  layerCount,
						int32  baseArrayLayer,
						uint32 mipCount
)
{
	VkImageMemoryBarrier barrier = f_vk_图像屏障();
	barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	barrier.pNext = NULL;
	barrier.srcAccessMask = 0;
	barrier.dstAccessMask = 0;
	barrier.oldLayout = old_image_layout;
	barrier.newLayout = new_image_layout;
	//barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	//barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	barrier.image = image;
	barrier.subresourceRange.aspectMask = aspectMask;
	barrier.subresourceRange.baseMipLevel = 0;
	barrier.subresourceRange.levelCount = mipCount;
	barrier.subresourceRange.baseArrayLayer = baseArrayLayer;
	barrier.subresourceRange.layerCount = layerCount;//数组层的数量


	VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
	VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;

	bool 帧写入 = new_image_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && old_image_layout == VK_IMAGE_LAYOUT_GENERAL;

	if ( (old_image_layout == VK_IMAGE_LAYOUT_UNDEFINED && (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)) || 帧写入) {
		barrier.srcAccessMask = 0;
		barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;

		src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
		dest_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
	}
	else if (old_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
		barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
		barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;

		src_stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
		dest_stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
	}



	switch (old_image_layout) {
		case VK_IMAGE_LAYOUT_UNDEFINED:							barrier.srcAccessMask = 0; break;
		case VK_IMAGE_LAYOUT_PREINITIALIZED:					barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; break;
		case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:			barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; break;
		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:	barrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; break;
		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:				barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; break;
		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:				barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; break;
		case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:			barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; break;
		default:
			break;
	}

	switch (new_image_layout) {
		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:				barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; break;
		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:				barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; break;
		case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:			barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; break;
		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:	barrier.dstAccessMask = barrier.dstAccessMask | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; break;
		case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
			if (barrier.srcAccessMask == 0) {
				barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
			}
			barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
			break;
		default:
			break;
	}

	vkCmdPipelineBarrier(cmd, src_stages, dest_stages, 0, 0, NULL, 0, NULL, 1, &barrier);

}

void f_vkImage_着色器读写布局(VkCommandBuffer cmd, VkImage image, VkImageAspectFlags aspectMask, int32 layerCount, int32 baseArrayLayer) {
	VkImageMemoryBarrier barrier = {};
	barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; // 或其他目标布局
	barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
	barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; // 假设图像将被着色器读取

	barrier.subresourceRange.aspectMask = aspectMask;
	barrier.subresourceRange.baseMipLevel = 0;
	barrier.subresourceRange.levelCount = 1;
	barrier.subresourceRange.baseArrayLayer = baseArrayLayer;
	barrier.subresourceRange.layerCount = layerCount;//数组层的数量


	// 根据图像的预期用途选择合适的 srcStageMask 和 dstStageMask
	vkCmdPipelineBarrier(
		cmd,
		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // 源阶段，适用于颜色附件写入
		VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // 目标阶段，适用于着色器读取
		0,
		0, nullptr,
		0, nullptr,
		1, &barrier);
}

void f_vkImage_帧缓存布局(VkCommandBuffer cmd, VkImage image, VkImageAspectFlags aspectMask, int32 layerCount, int32 baseArrayLayer) {
	VkImageMemoryBarrier barrier = {};
	//barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	//barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; // 当前的图像布局
	//barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // 目标布局，用作颜色附件
	//barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; // 图像在旧布局中的访问类型
	//barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // 图像在新布局中的访问类型
	//barrier.image = image; // 你的图像句柄
	//barrier.subresourceRange.aspectMask = aspectMask;
	//barrier.subresourceRange.baseMipLevel = 0;
	//barrier.subresourceRange.levelCount = 1;
	//barrier.subresourceRange.baseArrayLayer = baseArrayLayer;
	//barrier.subresourceRange.layerCount = layerCount;
	//
	//vkCmdPipelineBarrier(
	//	cmd,
	//	VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // 源阶段，着色器读取
	//	VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // 目标阶段，颜色附件输出
	//	0,
	//	0, nullptr,
	//	0, nullptr,
	//	1, &barrier); // 图像布局转换


	barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; // 或者当前的布局
	barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	barrier.image = image;
	barrier.subresourceRange.aspectMask = aspectMask;
	barrier.subresourceRange.baseMipLevel = 0;
	barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
	barrier.subresourceRange.baseArrayLayer = baseArrayLayer;
	barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;

	vkCmdPipelineBarrier(
		cmd,
		VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // 等待所有命令完成后再进行布局转换
		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // 接下来图像将被用作颜色附件
		0,
		0, nullptr,
		0, nullptr,
		1, &barrier
	);
}



void f_releaseImage(VkDevice dev, S_VkImage* tex) {
	if (tex->m_Mem) {
		
		if(tex->m_CubeView) {
			for (uint32 i = 0; i < 6; ++i) {
				vkDestroyImageView(dev, (tex->m_CubeView[i]), nullptr);
			}
			free(tex->m_CubeView);
		}
		if (tex->m_Cube纹理信息) {
			free(tex->m_Cube纹理信息);
		}

		vkDestroyImageView(dev, (tex->m_View), nullptr);
		tex->m_View = {};

		vkDestroyImage(dev, tex->m_Image, nullptr);
		vkFreeMemory(dev, tex->m_Mem, nullptr);

		tex->m_Image = nullptr;
		tex->m_Mem = nullptr;

		tex->m_CubeView = nullptr;
		tex->m_Cube纹理信息 = nullptr;
	}
}


inline VkMemoryRequirements f_get图像内存配置(const VkDevice& dev, const VkImage& i) {
	VkMemoryRequirements mem_reqs;
	vkGetImageMemoryRequirements(dev, i, &mem_reqs);
	return mem_reqs;
}




inline VkSamplerAddressMode f_转VK纹理拉伸方式(E_纹理拉伸方式 方式) {
	switch (方式) {
		case e_重复:		return VK_SAMPLER_ADDRESS_MODE_REPEAT;
		case e_镜像重复:	return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
		case e_边缘:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
		case e_镜像边缘:	return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
		case e_边框:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
			break;
		default:
			break;
	}
	return VK_SAMPLER_ADDRESS_MODE_REPEAT;
}


/*VkImageUsageFlags f_get纹理用途(E_纹理用途 用途) {
	switch (用途)
	{
	case e_采样:			return VK_IMAGE_USAGE_SAMPLED_BIT;
	case e_暂存附件:		return VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
	case e_颜色附件:		return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
	case e_深度模板附件:	return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
	case e_存储:			return VK_IMAGE_USAGE_STORAGE_BIT;
	case e_暂存源:			return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	case e_暂存目标:		return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	case e_输入附件:		return VK_IMAGE_USAGE_TRANSFER_DST_BIT;
	case e_SHADING_RATE:			return VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV;
	case e_FRAGMENT_DENSITY_MAP:	return VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT;
	default:
		break;
	}

	return VK_IMAGE_USAGE_SAMPLED_BIT;
}*/


VkImage f_tex_创建图像(VkDevice& dev, VkFormat 格式, E_纹理维度类型 类型, uvec3 size, uint32 用途, E_MS次数 采样, uint32 mip) {
	VkImageCreateInfo 图像创建信息 = {};
	图像创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
	图像创建信息.pNext = NULL;
	图像创建信息.imageType = f_转VK纹理类型(类型);
	图像创建信息.format = 格式;
	图像创建信息.extent.width = size.x;
	图像创建信息.extent.height = size.y;
	图像创建信息.extent.depth = 1;
	图像创建信息.mipLevels = mip;
	
	图像创建信息.samples = f_get多重采样Bits(采样);
	图像创建信息.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
	图像创建信息.usage = 用途;
	图像创建信息.queueFamilyIndexCount = 0;
	图像创建信息.pQueueFamilyIndices = 0;
	图像创建信息.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
	图像创建信息.tiling = VK_IMAGE_TILING_OPTIMAL;
	
	switch (类型) {
		case e_1D: 
		case e_2D: 
		case e_3D: 
		case e_1D_Array: 
		case e_2D_Array:
			图像创建信息.flags = 0;
			图像创建信息.arrayLayers = size.z;
			break;
		case e_CUBE: 
		case e_CUBE_Array:
			图像创建信息.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
			图像创建信息.arrayLayers = 6;
			break;
		default:
			break;
	}

	VkImage Image;
	auto res = vkCreateImage(dev, &图像创建信息, NULL, &Image);
	assert(res == VK_SUCCESS);
	return Image;
}

void f_tex_分配图像内存(S_设备环境& ctx, S_VkImage& image) {
	//auto rf = f_vk_get绘图框架(ctx);
	auto rt = f_vk_get绘图环境(ctx);

	auto 内存配置 = f_get图像内存配置(rt->m_设备, image.m_Image);
	VkMemoryAllocateInfo 内存分配信息 = {};
	内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	内存分配信息.pNext = NULL;
	内存分配信息.allocationSize = 内存配置.size;
	内存分配信息.memoryTypeIndex = f_内存类型索引(rt->m_内存属性, 内存配置.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

	auto res = vkAllocateMemory(rt->m_设备, &内存分配信息, NULL, &image.m_Mem);
	if (res != VK_SUCCESS) {
		DEF_记录日志("vulkan vkAllocateMemory 失败:" + std::to_string(res) + " " + std::string(__FILE__) + " 行:" + std::to_string(__LINE__));
	}
	assert(res == VK_SUCCESS);
	res = vkBindImageMemory(rt->m_设备, image.m_Image, image.m_Mem, 0);
	if (res != VK_SUCCESS) {
		DEF_记录日志("vulkan vkBindImageMemory 失败:" + std::to_string(res) + " " + std::string(__FILE__) + " 行:" + std::to_string(__LINE__));
	}
	assert(res == VK_SUCCESS);

}

void f_tex_创建图像视图(VkDevice& dev, S_VkImage& image, VkImageAspectFlagBits ImageAspect, VkFormat 格式, E_纹理维度类型 类型, uint32 层数量, uint32 布局) {
	VkImageViewCreateInfo 图像视口创建信息 = {};
	图像视口创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
	图像视口创建信息.pNext = NULL;

	图像视口创建信息.format = 格式;
	switch (格式) {
		case VK_FORMAT_R8_UNORM:
		case VK_FORMAT_R8_SNORM:
		case VK_FORMAT_R8_USCALED:
		case VK_FORMAT_R8_SSCALED:
		case VK_FORMAT_R8_UINT:
		case VK_FORMAT_R8_SINT:
		case VK_FORMAT_R8_SRGB:
		case VK_FORMAT_R16_UNORM:
		case VK_FORMAT_R16_SNORM:
		case VK_FORMAT_R16_UINT:
		case VK_FORMAT_R16_SINT:
		case VK_FORMAT_R32_SFLOAT:
		case VK_FORMAT_R64_UINT:
		case VK_FORMAT_R64_SINT:
		case VK_FORMAT_R64_SFLOAT:
		
			图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
			图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_R;
			图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_R;
			图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_R;
			break;

		
		case VK_FORMAT_R32_UINT:
		case VK_FORMAT_R32_SINT:
		case VK_FORMAT_D32_SFLOAT:
			图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
			图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
			图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
			图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
			break;

		default:
			图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
			图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_G;
			图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_B;
			图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_A;
			break;
	}

	图像视口创建信息.subresourceRange.aspectMask = ImageAspect;
	图像视口创建信息.subresourceRange.baseMipLevel = 0;
	图像视口创建信息.subresourceRange.levelCount = image.m_Mip;
	
	
	图像视口创建信息.viewType = f_转VK纹理视图类型(类型);
	图像视口创建信息.flags = 0;
	图像视口创建信息.image = image.m_Image;

	图像视口创建信息.subresourceRange.baseArrayLayer = 0;

	switch (类型) {
		case e_1D:
		case e_2D:
		case e_3D:
		case e_1D_Array:
		case e_2D_Array: {
			图像视口创建信息.subresourceRange.layerCount = 层数量;
			break;
		}

		case e_CUBE:
		case e_CUBE_Array: {
			图像视口创建信息.subresourceRange.layerCount = 6;
			break;
		}
		default:
			break;
	}

	//image.m_布局 = VK_IMAGE_LAYOUT_UNDEFINED;
	//image.m_布局 = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
	//image.m_布局 = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	image.m_布局 = VkImageLayout(布局);
	
	//image.m_View = (VkImageView*)calloc(sizeof(VkImageView), 1);
	//image.m_纹理信息 = (VkDescriptorImageInfo*)calloc(sizeof(VkDescriptorImageInfo), 1);
	auto res = vkCreateImageView(dev, &图像视口创建信息, NULL, &image.m_View);
	assert(res == VK_SUCCESS);


	image.m_纹理信息.imageLayout = image.m_布局;
	image.m_纹理信息.imageView = image.m_View;
	if (image.m_采样器) image.m_纹理信息.sampler = dynamic_cast<S_Vk纹理采样器*>(image.m_采样器)->m_采样器;


}

void f_tex_销毁图像视图(VkDevice& dev, S_VkImage& image) {
	vkDestroyImageView(dev, image.m_View, nullptr);
	image.m_View = {};
}



void f_tex_创建独立纹理视图(S_纹理* tex, bool 颜色) {
	auto& image = *dynamic_cast<S_VkImage*>(tex);

	VkImageViewCreateInfo 图像视口创建信息 = {};
	图像视口创建信息.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
	图像视口创建信息.pNext = NULL;

	图像视口创建信息.format = f_vk_getVK图像格式(tex->m_格式);
	switch (图像视口创建信息.format) {
		case VK_FORMAT_R8_UNORM:
		case VK_FORMAT_R8_SNORM:
		case VK_FORMAT_R8_USCALED:
		case VK_FORMAT_R8_SSCALED:
		case VK_FORMAT_R8_UINT:
		case VK_FORMAT_R8_SINT:
		case VK_FORMAT_R8_SRGB:
		case VK_FORMAT_R16_UNORM:
		case VK_FORMAT_R16_SNORM:
		case VK_FORMAT_R16_UINT:
		case VK_FORMAT_R16_SINT:
		case VK_FORMAT_R32_SFLOAT:
		case VK_FORMAT_R64_UINT:
		case VK_FORMAT_R64_SINT:
		case VK_FORMAT_R64_SFLOAT:

			图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
			图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_R;
			图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_R;
			图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_R;
			break;


		case VK_FORMAT_R32_UINT:
		case VK_FORMAT_R32_SINT:
		case VK_FORMAT_D32_SFLOAT:
			图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
			图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
			图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
			图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
			break;

		default:
			图像视口创建信息.components.r = VK_COMPONENT_SWIZZLE_R;
			图像视口创建信息.components.g = VK_COMPONENT_SWIZZLE_G;
			图像视口创建信息.components.b = VK_COMPONENT_SWIZZLE_B;
			图像视口创建信息.components.a = VK_COMPONENT_SWIZZLE_A;
			break;
	}

	图像视口创建信息.subresourceRange.aspectMask = image.m_ImageAspect;
	图像视口创建信息.subresourceRange.baseMipLevel = 0;
	图像视口创建信息.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
	图像视口创建信息.subresourceRange.layerCount = 1;

	图像视口创建信息.viewType = VK_IMAGE_VIEW_TYPE_2D;
	图像视口创建信息.flags = 0;
	图像视口创建信息.image = image.m_Image;


	
	VkDevice dev = (VkDevice)image.m_Ctx.m_逻辑设备.设备;


	switch (image.m_ImageAspect) {
		case VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT: {
			
			break;
		}
		case VkImageAspectFlagBits::VK_IMAGE_ASPECT_DEPTH_BIT: {
			image.m_布局 = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
			break;
		}
		default:
			break;
	}

	image.m_CubeView = (VkImageView*)calloc(sizeof(VkImageView), 6);
	image.m_Cube纹理信息 = (VkDescriptorImageInfo*)calloc(sizeof(VkDescriptorImageInfo), 6);


	for (uint32 i = 0; i < 6; ++i) {
		图像视口创建信息.subresourceRange.baseArrayLayer = i;
	
		auto res = vkCreateImageView(dev, &图像视口创建信息, NULL, &image.m_CubeView[i]);
		assert(res == VK_SUCCESS);
	
		image.m_Cube纹理信息[i].imageLayout = image.m_布局;
		image.m_Cube纹理信息[i].imageView = image.m_CubeView[i];
		if(image.m_采样器) image.m_Cube纹理信息[i].sampler = dynamic_cast<S_Vk纹理采样器*>(image.m_采样器)->m_采样器;
	}

}

void f_tex_立方体纹理深度布局(S_纹理* tex, uint32 层) {
	auto& image = *dynamic_cast<S_VkImage*>(tex);

	VkImageMemoryBarrier imageMemoryBarrier = {};
	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	imageMemoryBarrier.pNext = NULL;
	imageMemoryBarrier.srcAccessMask = 0; // 指定旧布局的访问类型
	imageMemoryBarrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; // 指定新布局的访问类型
	imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; // 旧布局
	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; // 新布局
	imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.image = image.m_Image;
	imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
	imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
	imageMemoryBarrier.subresourceRange.levelCount = 1;
	imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
	imageMemoryBarrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;

	S_VK渲染环境& 配置 = *((S_VK渲染环境*)(tex->m_Ctx.m_逻辑设备.渲染环境));

	auto cmd = f_vk创建命令缓存(&配置);
	f_vk绑定命令缓存(&配置, cmd);

	// 在命令缓冲区中插入一个管线障碍物，以转换图像布局
	vkCmdPipelineBarrier(
		cmd,
		VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, // 指定旧布局的最后一个着色阶段
		VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // 指定新布局的第一个着色阶段
		0,
		0, NULL, // 无内存障碍物
		0, NULL, // 无缓冲区内存障碍物
		1, &imageMemoryBarrier // 一个图像内存障碍物
	);

	f_vk刷新命令缓存(&配置, cmd, true);
}

void f_tex_set纹理颜色附件布局(S_纹理* tex, uint32 层数量) {
	auto& image = *dynamic_cast<S_VkImage*>(tex);

	S_VK渲染环境& 配置 = *((S_VK渲染环境*)(tex->m_Ctx.m_逻辑设备.渲染环境));
	auto cmd = f_vk创建命令缓存(&配置);
	f_vk绑定命令缓存(&配置, cmd);


	VkImageMemoryBarrier imageMemoryBarrier = {};
	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	imageMemoryBarrier.pNext = NULL;
	imageMemoryBarrier.srcAccessMask = 0; // 源访问掩码，根据旧布局设置
	imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
	imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;  
	imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.image = image.m_Image; // 图像句柄
	imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;  
	imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
	imageMemoryBarrier.subresourceRange.levelCount = 1;
	imageMemoryBarrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; // 应用到所有层
	

	for (uint32 i = 0; i < 层数量; ++i) {
		imageMemoryBarrier.subresourceRange.baseArrayLayer = i;

		// 在命令缓冲区中插入布局转换
		vkCmdPipelineBarrier(
			cmd,
			VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // 旧布局的最后一个阶段
			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // 新布局的第一个阶段
			0,
			0, NULL, // 无依赖项
			0, NULL, // 无缓冲区内存障碍物
			1, &imageMemoryBarrier // 图像内存障碍物
		);
	}
	
	f_vk刷新命令缓存(&配置, cmd, true);
}

void f_tex_set着色器采样布局(S_纹理* tex, uint32 层数量) {
	auto& image = *dynamic_cast<S_VkImage*>(tex);

	S_VK渲染环境& 配置 = *((S_VK渲染环境*)(tex->m_Ctx.m_逻辑设备.渲染环境));
	auto cmd = f_vk创建命令缓存(&配置);
	f_vk绑定命令缓存(&配置, cmd);


	VkImageMemoryBarrier imageMemoryBarrier = {};
	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	imageMemoryBarrier.pNext = NULL;
	imageMemoryBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
	imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
	imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
	imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.image = image.m_Image; // 图像句柄
	imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
	imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
	imageMemoryBarrier.subresourceRange.levelCount = 1;
	imageMemoryBarrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; // 应用到所有层

	for (uint32 i = 0; i < 层数量; ++i) {
		imageMemoryBarrier.subresourceRange.baseArrayLayer = i;

		// 在命令缓冲区中插入布局转换
		vkCmdPipelineBarrier(
			cmd,
			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	// 旧布局的最后一个阶段
			VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,			// 新布局的第一个阶段
			0,
			0, NULL, // 无依赖项
			0, NULL, // 无缓冲区内存障碍物
			1, &imageMemoryBarrier // 图像内存障碍物
		);
	}

	f_vk刷新命令缓存(&配置, cmd, true);
}


void f_tex_set帧写入布局(S_纹理* tex, uint32 层数量) {
	auto& image = *dynamic_cast<S_VkImage*>(tex);

	S_VK渲染环境& 配置 = *((S_VK渲染环境*)(tex->m_Ctx.m_逻辑设备.渲染环境));
	auto cmd = f_vk创建命令缓存(&配置);
	f_vk绑定命令缓存(&配置, cmd);


	VkImageMemoryBarrier imageMemoryBarrier = {};
	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	imageMemoryBarrier.pNext = NULL;
	imageMemoryBarrier.srcAccessMask = 0;
	imageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
	imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
	imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
	imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.image = image.m_Image; // 图像句柄
	imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
	imageMemoryBarrier.subresourceRange.baseMipLevel = 0;
	imageMemoryBarrier.subresourceRange.levelCount = 1;
	imageMemoryBarrier.subresourceRange.layerCount = 层数量; // 应用到所有层
	imageMemoryBarrier.subresourceRange.baseArrayLayer = 0;
	
	
	// 在命令缓冲区中插入布局转换
	vkCmdPipelineBarrier(
		cmd,
		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,	// 旧布局的最后一个阶段
		VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT ,			// 新布局的第一个阶段
		0,
		0, NULL, // 无依赖项
		0, NULL, // 无缓冲区内存障碍物
		1, &imageMemoryBarrier // 图像内存障碍物
	);
	

	f_vk刷新命令缓存(&配置, cmd, true);

	image.m_纹理信息.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}




S_Vk图像管理::~S_Vk图像管理() {
	
}

void S_Vk图像管理::f_释放图像(VkDevice& dev, S_VkImage* image) {
	//uint32 key = image->m_ID;
	//if (g_纹理容器.f_Key存在(key)) {
	//	auto t = g_纹理容器[key];
	//
	//	f_releaseImage(dev, t);
	//	free(t);
	//
	//	g_纹理容器.f_remove(key);
	//
	//} else if(image != NULL) {
	//	for (auto& t : g_纹理容器.gData序列容器) {
	//		f_releaseImage(dev, t);
	//		free(t);
	//	}
	//}
	
	//delete image;
}

S_VkImage* S_Vk图像管理::f_创建图像视图(VkDevice& dev, VkImage image, const VkFormat& 格式, uint32 布局) {
	S_VkImage* iObj = new S_VkImage;

	iObj->m_Mem = nullptr;
	iObj->m_View = 0;
	iObj->m_Image = image;
	iObj->m_ImageAspect = VK_IMAGE_ASPECT_COLOR_BIT ;

	f_tex_创建图像视图(dev, *iObj, VK_IMAGE_ASPECT_COLOR_BIT, 格式, E_纹理维度类型::e_2D, 1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);

	//iObj->m_布局 = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
	//iObj->m_布局 = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

	iObj->m_纹理信息.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	return iObj;
}

S_VkImage* S_Vk图像管理::f_创建纹理图像(S_设备环境& ctx, const VkFormat& 格式, uvec3 size, E_纹理维度类型 类型, uint32 用途, E_MS次数 采样, uint32 key) {
	S_VkImage& obj = *new S_VkImage();
	VkDevice dev = f_vk_getDevice(ctx);
	//auto* 绘图框架 = f_vk_get绘图框架(ctx);
	auto* 绘图环境 = f_vk_get绘图环境(ctx);

	VkResult res;
	obj.m_ImageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
	obj.m_采样 = 采样;
	obj.m_Image = f_tex_创建图像(dev, 格式, 类型, size, 用途, 采样);


	auto 内存配置 = f_get图像内存配置(dev, obj.m_Image);
	VkMemoryAllocateInfo 内存分配信息 = {};
	内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	内存分配信息.pNext = NULL;
	内存分配信息.allocationSize = 内存配置.size;
	内存分配信息.memoryTypeIndex = f_内存类型索引(绘图环境->m_内存属性, 内存配置.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

	res = vkAllocateMemory(dev, &内存分配信息, NULL, &obj.m_Mem);
	assert(res == VK_SUCCESS);
	res = vkBindImageMemory(dev, obj.m_Image, obj.m_Mem, 0);
	assert(res == VK_SUCCESS);


	f_tex_创建图像视图(dev, obj, VK_IMAGE_ASPECT_COLOR_BIT, 格式, 类型, size.z, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);

	return &obj;
}

S_VkImage* S_Vk图像管理::f_创建帧缓存图像(VkDevice& dev, VkPhysicalDeviceMemoryProperties 内存属性, VkFormat 格式, E_纹理维度类型 类型, uvec3 size, E_MS次数 采样, uint32 用途, uint32 层) {
	S_VkImage& obj = *new S_VkImage;
	obj.m_ImageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
	obj.m_采样 = 采样;

	VkResult res;
	obj.m_Image = f_tex_创建图像(dev, 格式, 类型, size, 用途, 采样, 层);


	auto 内存配置 = f_get图像内存配置(dev, obj.m_Image);
	VkMemoryAllocateInfo 内存分配信息 = {};
	内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	内存分配信息.pNext = NULL;
	内存分配信息.allocationSize = 内存配置.size;
	内存分配信息.memoryTypeIndex = f_内存类型索引(内存属性, 内存配置.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
	

	uint8 分配内存次数 = 0;
	To_重新分配内存:
	res = vkAllocateMemory(dev, &内存分配信息, NULL, &obj.m_Mem);
	assert(res == VK_SUCCESS);

	res = vkBindImageMemory(dev, obj.m_Image, obj.m_Mem, 0);
	assert(res == VK_SUCCESS);


	f_tex_创建图像视图(dev, obj, VK_IMAGE_ASPECT_COLOR_BIT, 格式, 类型, size.z, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
	return &obj;
}

S_VkImage * S_Vk图像管理::f_创建深度缓存图像(VkDevice& dev
											, VkPhysicalDeviceMemoryProperties 内存属性
											, VkPhysicalDeviceProperties 物理设备属性
											, VkFormat 格式
											, uvec3 size
											, E_MS次数 采样
											, E_纹理维度类型 类型 ) {
	
	S_VkImage& obj = *new S_VkImage;

	obj.m_ImageAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
	obj.m_采样 = 采样;
	obj.m_格式 = E_纹理格式::e_tf_D32F;

	VkResult res;
	obj.m_用途 = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
	//obj.m_用途 = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
	obj.m_Image = f_tex_创建图像(dev, 格式, 类型, size, obj.m_用途, 采样);
	


	auto 内存配置 = f_get图像内存配置(dev, obj.m_Image);
	VkMemoryAllocateInfo 内存分配信息 = {};
	内存分配信息.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	内存分配信息.pNext = NULL;
	内存分配信息.allocationSize = 内存配置.size;
	内存分配信息.memoryTypeIndex = f_内存类型索引(内存属性, 内存配置.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
	//f_内存类型_from_properties();
	res = vkAllocateMemory(dev, &内存分配信息, NULL, &obj.m_Mem);
	assert(res == VK_SUCCESS);
	res = vkBindImageMemory(dev, obj.m_Image, obj.m_Mem, 0);
	assert(res == VK_SUCCESS);


	f_tex_创建图像视图(dev, obj, VK_IMAGE_ASPECT_DEPTH_BIT, 格式, 类型, size.z, VK_IMAGE_LAYOUT_GENERAL);

	return &obj;
}




VkFormat findSupportedFormat(	const VkPhysicalDevice phyDev, 
								const vector<VkFormat>& candidates, 
								VkImageTiling tiling, 
								VkFormatFeatureFlags features)
{
	for (VkFormat format : candidates) {
		VkFormatProperties props;
		vkGetPhysicalDeviceFormatProperties(phyDev, format, &props);

		//是否支持瓦片组织方式
		if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) {
			return format;
		}
		//是否支持最优瓦片组织方式
		else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) {
			return format;
		}
	}

	throw std::runtime_error("查找图像格式失败");
}

VkFormat f_findDepthFormat(const VkPhysicalDevice phyDev) {
	return findSupportedFormat(phyDev,
		{ VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D16_UNORM },
		VK_IMAGE_TILING_OPTIMAL,																					//是否支持瓦片组织方式
		VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT																//是否支持最优瓦片组织方式
	);
}






void f_VkImage_构建(S_VkImage* obj, S_设备环境& ctx) {
	VkDevice		逻辑设备	= (VkDevice)(ctx.m_逻辑设备.设备);
	S_物理设备属性* prop		= (S_物理设备属性*)ctx.m_物理设备.物理设备属性;
	
	f_releaseImage(逻辑设备, obj);

	obj->m_Image = f_tex_创建图像(逻辑设备, f_vk_getVK图像格式(obj->m_格式), obj->m_类型, obj->m_Size, obj->m_用途, obj->m_采样, obj->m_Mip);
	f_tex_分配图像内存(ctx, *obj);
	f_tex_创建图像视图(逻辑设备, *obj, obj->m_ImageAspect, f_vk_getVK图像格式(obj->m_格式), obj->m_类型, obj->m_Size.z, VK_IMAGE_LAYOUT_GENERAL);
}

VkImageMemoryBarrier f_vk_图像屏障() {
	VkImageMemoryBarrier imageMemoryBarrier{};
	imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
	imageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	imageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
	return imageMemoryBarrier;
}





S_Vk纹理采样器::S_Vk纹理采样器(VkDevice& dev, S_纹理采样器创建参数 参数) {
	VkSamplerCreateInfo info = {};

	info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
	info.magFilter = VK_FILTER_LINEAR;
	info.minFilter = VK_FILTER_NEAREST;
	info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
	info.addressModeU = f_转VK纹理拉伸方式(参数.U);
	info.addressModeV = f_转VK纹理拉伸方式(参数.V);
	info.addressModeW = f_转VK纹理拉伸方式(参数.W);
	info.minLod = 0.0;
	info.maxLod = 0.5;
	info.mipLodBias = 0;

	info.anisotropyEnable = true;
	info.maxAnisotropy = 16;
	info.compareEnable = false;

	switch (参数.m_预设预设) {
		case E_预设颜色::e_黑色: {
			info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
			break;
		}
		case E_预设颜色::e_白色: {
			info.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
			break;
		}
		default:
			info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
			break;
	}
	vkCreateSampler(dev, &info, 0, &m_采样器);
}

S_Vk纹理采样器::~S_Vk纹理采样器() {
	VkDevice 逻辑设备 = (VkDevice)(m_Ctx.m_逻辑设备.设备);
	vkDestroySampler(逻辑设备, m_采样器, nullptr);
}
